<?php

namespace App\Services\Auth;

class JwtService
{
    /**
     * 生成MD5加密钥
     * @param int $uid 用户ID
     * @param int $timestamp 时间戳（可选，默认当前时间）
     * @return string 返回加密钥字符串
     */
    public static function createToken($uid = null, $timestamp = null)
    {
        try {
            $config = config('jwt.default');
            
            // 如果没有传入时间戳，使用当前时间
            if ($timestamp === null) {
                $timestamp = time();
            }
            
            // 构建加密数据
            $data = [
                'uid' => $uid,
                'timestamp' => $timestamp,
                'expire' => $timestamp + intval($config['expire'] / 1000), // 过期时间
                'iss' => $config['iss'], // 签发人
                'aud' => $config['aud'], // 接收人
                'id' => $config['id']    // 标识ID
            ];
            
            // 将数据转为JSON字符串
            $jsonData = json_encode($data);
            
            // 使用base64编码数据部分
            $encodedData = base64_encode($jsonData);
            
            // 生成签名：使用数据 + 密钥进行MD5加密
            $signature = md5($encodedData . $config['sign']);
            
            // 返回格式：编码数据.签名
            return $encodedData . '.' . $signature;
            
        } catch (\Exception $e) {
            // 记录详细错误信息
            \Log::error('MD5 Token创建失败', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'uid' => $uid,
                'timestamp' => $timestamp
            ]);
            throw $e;
        }
    }

    /**
     * 验证MD5加密钥
     * @param string $token 加密钥
     * @return int 返回用户ID，验证失败返回0
     */
    public static function verifyToken($token = null)
    {
        try {
            $config = config('jwt.default');
            
            // 检测是否接收到了token
            if (empty($token)) {
                return 0;
            }
            
            // 分割token：数据部分.签名部分
            $parts = explode('.', $token);
            if (count($parts) !== 2) {
                return 0;
            }
            
            list($encodedData, $signature) = $parts;
            
            // 验证签名
            $expectedSignature = md5($encodedData . $config['sign']);
            if ($signature !== $expectedSignature) {
                return 0;
            }
            
            // 解码数据
            $jsonData = base64_decode($encodedData);
            if ($jsonData === false) {
                return 0;
            }
            
            $data = json_decode($jsonData, true);
            if ($data === null) {
                return 0;
            }
            
            // 检查必要字段
            if (!isset($data['uid'], $data['timestamp'], $data['expire'])) {
                return 0;
            }
            
            // 检查是否过期
            $currentTime = time();
            if ($currentTime > $data['expire']) {
                return 0;
            }
            
            // 检查签发人和接收人（可选验证）
            if (isset($config['iss']) && $data['iss'] !== $config['iss']) {
                return 0;
            }
            
            if (isset($config['aud']) && $data['aud'] !== $config['aud']) {
                return 0;
            }
            
            // 验证通过，返回用户ID
            return $data['uid'];
            
        } catch (\Exception $e) {
            // 记录详细错误信息
            \Log::error('MD5 Token验证失败', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'token' => $token
            ]);
            return 0;
        }
    }
    
    /**
     * 生成API签名
     * @param array $params 请求参数
     * @param string $secret 密钥（可选，默认使用配置中的密钥）
     * @return string 返回MD5签名
     */
    public static function generateSignature($params = [], $secret = null)
    {
        try {
            if ($secret === null) {
                $config = config('jwt.default');
                $secret = $config['sign'];
            }
            
            // 移除签名字段（如果存在）
            unset($params['sign'], $params['signature']);
            
            // 按键名排序
            ksort($params);
            
            // 构建查询字符串
            $queryString = http_build_query($params);
            
            // 生成签名
            return md5($queryString . $secret);
            
        } catch (\Exception $e) {
            \Log::error('API签名生成失败', [
                'error' => $e->getMessage(),
                'params' => $params
            ]);
            throw $e;
        }
    }
    
    /**
     * 验证API签名
     * @param array $params 请求参数
     * @param string $signature 待验证的签名
     * @param string $secret 密钥（可选，默认使用配置中的密钥）
     * @return bool 验证结果
     */
    public static function verifySignature($params = [], $signature = '', $secret = null)
    {
        try {
            $expectedSignature = self::generateSignature($params, $secret);
            return $signature === $expectedSignature;
            
        } catch (\Exception $e) {
            \Log::error('API签名验证失败', [
                'error' => $e->getMessage(),
                'params' => $params,
                'signature' => $signature
            ]);
            return false;
        }
    }
}
